<script setup lang="ts">
import { computed, watch } from 'vue';
import { useForm } from 'vee-validate';
import { toTypedSchema } from '@vee-validate/zod';
import type { FormSchema, FormFieldConfig } from './types';
import { Button } from '@/components/ui/button';
import {
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
  FormDescription,
} from '@/components/ui/form';
import FormFieldRenderer from './FormFieldRenderer.vue';

interface Props {
  schema: FormSchema;
  initialValues?: Record<string, any>;
  loading?: boolean;
  submitButtonText?: string;
  cancelButtonText?: string;
  showCancelButton?: boolean;
}

interface Emits {
  submit: [values: Record<string, any>];
  cancel: [];
}

const props = withDefaults(defineProps<Props>(), {
  loading: false,
  submitButtonText: '提交',
  cancelButtonText: '取消',
  showCancelButton: true,
});

const emit = defineEmits<Emits>();

// 创建表单实例
const { handleSubmit, resetForm, setValues, values } = useForm({
  validationSchema: toTypedSchema(props.schema.validationSchema),
  initialValues: props.initialValues || props.schema.initialValues || {},
});

// 监听初始值变化
watch(() => props.initialValues, newValues => {
  if (newValues) {
    setValues(newValues);
  }
}, { immediate: true });

// 计算布局样式
const gridStyle = computed(() => {
  const columns = props.schema.config.layout?.columns || 2;
  return `grid-cols-${columns}`;
});

// 计算字段网格样式的计算属性
function getFieldGridStyle(field: FormFieldConfig) {
  if (!field.grid?.span) {
    return {};
  }

  // 确保span值在有效范围内（1-12）
  const span = Math.min(Math.max(field.grid.span, 1), 12);
  return {
    'grid-column': `span ${span} / span ${span}`,
  };
}

// 处理字段可见性
function isFieldVisible(field: FormFieldConfig) {
  if (!field.conditional) {
    return true;
  }

  const { field: dependentField, value, operator = 'eq' } = field.conditional;
  const dependentValue = values.value[dependentField];

  switch (operator) {
    case 'eq':
      return dependentValue === value;
    case 'ne':
      return dependentValue !== value;
    case 'gt':
      return dependentValue > value;
    case 'lt':
      return dependentValue < value;
    case 'gte':
      return dependentValue >= value;
    case 'lte':
      return dependentValue <= value;
    case 'in':
      return Array.isArray(value) && value.includes(dependentValue);
    case 'notIn':
      return Array.isArray(value) && !value.includes(dependentValue);
    default:
      return true;
  }
}

// 提交处理
const onSubmit = handleSubmit(values => {
  emit('submit', values);
});

// 取消处理
function handleCancel() {
  resetForm();
  emit('cancel');
}

// TODO 重置表单
// function resetFormData() {
//   resetForm();
// }
</script>

<template>
  <form class="space-y-4" @submit="onSubmit">
    <div :class="`grid ${gridStyle} gap-4`">
      <div
        v-for="field of schema.config.fields"
        v-show="isFieldVisible(field)"
        :key="field.name"
        :style="getFieldGridStyle(field)"
      >
        <FormField
          #default="{ componentField }"
          :name="field.name"
        >
          <FormItem>
            <FormLabel>
              {{ field.label }}
              <span v-if="field.required" class="text-red-500">*</span>
            </FormLabel>
            <FormControl>
              <FormFieldRenderer
                :field="field"
                :component-field="componentField"
              />
            </FormControl>
            <FormDescription v-if="field.helpText">
              {{ field.helpText }}
            </FormDescription>
            <FormMessage />
          </FormItem>
        </FormField>
      </div>
    </div>

    <div class="flex justify-end space-x-2">
      <Button
        v-if="showCancelButton"
        type="button"
        variant="outline"
        @click="handleCancel"
      >
        {{ cancelButtonText }}
      </Button>
      <Button type="submit" :disabled="loading">
        {{ submitButtonText }}
      </Button>
    </div>
  </form>
</template>
